package com.ly.test.service.impl;

import com.ly.system.test.entity.RedisInfo;
import com.ly.test.service.IRedisService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * Redis 监控信息获取
 *
 * @author MrBird
 */
@Slf4j
@Service("redisService")
@RequiredArgsConstructor
public class RedisServiceImpl implements IRedisService {
    /**
     * redis性能信息记录
     */
    private static final Map<String, List<Map<String, Object>>> REDIS_METRICS = new HashMap<>(2);
    private final RedisConnectionFactory factory;

    /**
     * Redis详细信息
     */
    @Override
    public List<RedisInfo> getRedisInfo() {
        Properties info = factory.getConnection().info();
        List<RedisInfo> infoList = new ArrayList<>();
        for (Map.Entry<Object, Object> entry : info.entrySet()) {
            RedisInfo redisInfo = new RedisInfo();
            redisInfo.setKey(String.valueOf(entry.getKey()));
            redisInfo.setValue(String.valueOf(entry.getValue()));
            infoList.add(redisInfo);
        }
        return infoList;
    }

    @Override
    public Map<String, Object> getKeysSize() {
        Long dbSize = factory.getConnection().dbSize();
        Map<String, Object> map = new HashMap(5);
        map.put("create_time", System.currentTimeMillis());
        map.put("dbSize", dbSize);
        log.debug("--getKeysSize--: " + map.toString());
        return map;
    }

    @Override
    public Map<String, Object> getMemoryInfo() {
        Map<String, Object> map = null;
        Properties info = factory.getConnection().info();
        for (Map.Entry<Object, Object> entry : info.entrySet()) {
            String key = String.valueOf(entry.getKey());
            if ("used_memory".equals(key)) {
                map = new HashMap(5);
                map.put("used_memory", entry.getValue());
                map.put("create_time", System.currentTimeMillis());
            }
        }
        log.debug("--getMemoryInfo--: " + map.toString());
        return map;
    }

    /**
     * 获取历史性能指标
     *
     * @return
     * @author jeecg
     * @date 2024/5/14 14:57
     */
    @Override
    public Map<String, List<Map<String, Object>>> getMetricsHistory() {
        return REDIS_METRICS;
    }

    /**
     * 记录近一小时redis监控数据 <br/>
     * 60s一次,,记录存储keysize和内存
     *
     * @author jeecg
     * @date 2024/5/14 14:09
     */
    @Scheduled(fixedRate = 60000)
    public void recordCustomMetric() {
        List<Map<String, Object>> list = new ArrayList<>();
        if (REDIS_METRICS.containsKey("dbSize")) {
            list = REDIS_METRICS.get("dbSize");
        } else {
            REDIS_METRICS.put("dbSize", list);
        }
        if (list.size() > 60) {
            list.remove(0);
        }
        list.add(getKeysSize());
        list = new ArrayList<>();
        if (REDIS_METRICS.containsKey("memory")) {
            list = REDIS_METRICS.get("memory");
        } else {
            REDIS_METRICS.put("memory", list);
        }
        if (list.size() > 60) {
            list.remove(0);
        }
        list.add(getMemoryInfo());
    }
}
